package com.chen.dao.impl;


import com.chen.dao.BaseDAO;
import com.chen.pojo.PageBean;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;


@Repository("baseDAO")
// 用来声明持久层
@SuppressWarnings("all")
// 该批注是用来给编译器一条指令，告诉它对被批注的代码元素内部的某些警告保持静默。
@Transactional
public class BaseDAOImpl<T> implements BaseDAO<T> {

  private SessionFactory sessionFactory;

  public SessionFactory getSessionFactory() {
    return sessionFactory;
  }

  @Autowired
  public void setSessionFactory(SessionFactory sessionFactory) {
    this.sessionFactory = sessionFactory;
  }

  private Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
  }

  public Serializable save(T o) {
    return this.getCurrentSession().save(o);
  }

  public void delete(T o) {
    this.getCurrentSession().delete(o);
  }

  public int delete(String hql) {
    return this.getCurrentSession().createQuery(hql).executeUpdate();
  }

  public void update(T o) {
    this.getCurrentSession().update(o);
  }

  public void saveOrUpdate(T o) {
    this.getCurrentSession().saveOrUpdate(o);
  }

  public int saveOrUpdate(String hql) {
    return this.getCurrentSession().createQuery(hql).executeUpdate();
  }

  public List<T> find(String hql) {
    return this.getCurrentSession().createQuery(hql).list();
  }

  public List<T> find(String hql, Object[] param) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.length > 0) {
      for (int i = 0; i < param.length; i++) {
        q.setParameter(i, param[i]);
      }
    }
    // ====返回查询列表=========
    return q.list();
  }

  public List<T> find(String hql, List<Object> param) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.size() > 0) {
      for (int i = 0; i < param.size(); i++) {
        q.setParameter(i, param.get(i));
      }
    }
    // ====返回查询列表=========
    return q.list();
  }

  public List<T> find(String hql, Object[] param, PageBean pageBean) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.length > 0) {
      for (int i = 0; i < param.length; i++) {
        q.setParameter(i, param[i]);// 把传过来的参数设置到Query语句当中
      }
    }
    // 获取第一个记录数的位置(setFirstResult);设置结果集的最大记录数(setMaxResult)
    return q.setFirstResult(pageBean.getStart())
            .setMaxResults(pageBean.getPageSize()).list();
  }

  public List<T> find(String hql, List<Object> param, PageBean pageBean) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.size() > 0) {
      for (int i = 0; i < param.size(); i++) {
        q.setParameter(i, param.get(i));
      }
    }
    return q.setFirstResult(pageBean.getStart())
            .setMaxResults(pageBean.getPageSize()).list();
  }

  public T get(Class<T> c, Serializable id) {
    return (T) this.getCurrentSession().get(c, id);
  }

  public T get(String hql, Object[] param) {
    List<T> l = this.find(hql, param);
    if (l != null && l.size() > 0) {
      return l.get(0);
    } else {
      return null;
    }
  }

  public T get(String hql, List<Object> param) {
    List<T> l = this.find(hql, param);
    if (l != null && l.size() > 0) {
      return l.get(0);
    } else {
      return null;
    }
  }

  public Long count(String hql) {
    return (Long) this.getCurrentSession().createQuery(hql).uniqueResult();
  }

  public Long count(String hql, Object[] param) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.length > 0) {
      for (int i = 0; i < param.length; i++) {
        q.setParameter(i, param[i]);
      }
    }
    return (Long) q.uniqueResult();
  }

  public Long count(String hql, List<Object> param) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.size() > 0) {
      for (int i = 0; i < param.size(); i++) {
        q.setParameter(i, param.get(i));
      }
    }
    return (Long) q.uniqueResult();
  }

  public Integer executeHql(String hql) {
    return this.getCurrentSession().createQuery(hql).executeUpdate();
  }

  public Integer executeHql(String hql, Object[] param) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.length > 0) {
      for (int i = 0; i < param.length; i++) {
        q.setParameter(i, param[i]);
      }
    }
    return q.executeUpdate();
  }

  public Integer executeHql(String hql, List<Object> param) {
    Query q = this.getCurrentSession().createQuery(hql);
    if (param != null && param.size() > 0) {
      for (int i = 0; i < param.size(); i++) {
        q.setParameter(i, param.get(i));
      }
    }
    return q.executeUpdate();
  }

  /*
   * save()之后再调用merge，返回的是同一个instance，但其关联group对象会被更新
   * 如果在add一个对象之后，如果存在关联对象，并且需要再同一个hibernate session中进行回显， 则建议使用merge()方法。
   */
  public void merge(T o) {
    this.getCurrentSession().merge(o);
  }

  public Integer executeSql(String sql) {
    Query q = this.getCurrentSession().createSQLQuery(sql);
    return q.executeUpdate();
  }

}
